package edu.mapi.ir.viewer;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.Hashtable;
import java.util.Vector;

/**
 * @author ZP
 */
public class MousePaths implements IMapLayer {

	private Hashtable<Integer, Vector<Point2D>> paths = new Hashtable<Integer, Vector<Point2D>>();
	private Hashtable<Integer, Color> colors = new Hashtable<Integer, Color>();
	private BufferedImage img = null;
	private double lastZoom = 0;
	private Maze maze = null;
	
	public MousePaths(Maze maze) {
		this.maze = maze;
	}
	
	public void clearPaths() {
		paths.clear();		
	}
	
	
	public BufferedImage getLayerImage(double zoom) {
		if (img == null || zoom != lastZoom) {
			img = new BufferedImage((int)(maze.getWidth()*zoom), (int)(maze.getHeight()*zoom), BufferedImage.TYPE_INT_ARGB);
		}
		
		Graphics2D g = (Graphics2D) img.getGraphics();
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(new Color(255,255,255,100));
		g.translate(0, img.getHeight());
		g.scale(1, -1);

		for (Integer id : paths.keySet()) {
			g.setColor(colors.get(id));
			g.setStroke(new BasicStroke(2f));
			Vector<Point2D> pts = paths.get(id);
			if (pts.size() == 0)
				continue;
			Point2D lastPt = pts.get(0);
			
			for (int i = 1; i < pts.size(); i++) {
				g.draw(new Line2D.Double(lastPt.getX()*zoom,  lastPt.getY() * zoom, pts.get(i).getX() * zoom,  pts.get(i).getY() * zoom));
				lastPt = pts.get(i);			
			}
		}			
		lastZoom = zoom;

		return img;		
	}

	public boolean hasLayerChanged() {		
		return false;
	}
	
	public void addPoint(MousePlayer mp, Point2D pt) {
		if(!paths.containsKey(mp.getId())) {
			paths.put(mp.getId(), new Vector<Point2D>());
			if (!mp.isGhost())
				colors.put(mp.getId(), new Color(mp.getColor().getRed(), mp.getColor().getGreen(), mp.getColor().getBlue()));
			else
				colors.put(mp.getId(), new Color(mp.getColor().getRed(), mp.getColor().getGreen(), mp.getColor().getBlue(), 80));
		}
		
		if (pt.equals(getPreviousPoint(mp)))
			return;
		
		paths.get(mp.getId()).add(new Point2D.Double(pt.getX(), pt.getY()));
	}
	
	public Point2D getPreviousPoint(MousePlayer mp) {
		if (mp == null || paths == null || paths.isEmpty())
			return null;
		
		try   {
			return paths.get(mp.getId()).lastElement();
		}
		catch (Exception e) {
			return null;
		}		
	}
	
	public Color getPathColor(MousePlayer mp) {
		if (colors.containsKey(mp.getId())) {
			return colors.get(mp.getId());
		}
		return Color.red;
	}
}
